package com.example.gokchinesefoodmapmcdev.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.gokchinesefoodmapmcdev.dao.SysRoleDAO;
import com.example.gokchinesefoodmapmcdev.dao.SysUserDAO;
import com.example.gokchinesefoodmapmcdev.dao.SysUserRoleDAO;
import com.example.gokchinesefoodmapmcdev.entity.sys.SysRole;
import com.example.gokchinesefoodmapmcdev.entity.sys.SysUser;
import com.example.gokchinesefoodmapmcdev.entity.sys.SysUserRole;
import com.example.gokchinesefoodmapmcdev.service.ClientService;
import com.example.gokchinesefoodmapmcdev.util.CheckInfoUtils;
import com.example.gokchinesefoodmapmcdev.util.ResultData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;

@Service
public class ClientServiceImpl implements ClientService {
    /**
     * 角色前缀名
     */
    private final static String ROLE_PREFIX = "ROLE_";

    @Autowired
    private SysUserDAO sysUserDAO;

    @Autowired
    private SysUserRoleDAO sysUserRoleDAO;

    @Autowired
    private SysRoleDAO sysRoleDAO;

    @Override
    public ResultData chickSysUserInfo(SysUser sysUser) {
        // 密码、手机号判空
        if(StringUtils.isEmpty(sysUser.getPassword())){
            return ResultData.fail(ResultData.REGISTER_FAIL, "密码不能为空");
        }

        if(StringUtils.isEmpty(sysUser.getMobile())){
            return ResultData.fail(ResultData.REGISTER_FAIL, "手机号不能为空");
        }

        // 手机号、邮箱格式判断
        if(!CheckInfoUtils.isPhone(sysUser.getMobile())){
            return ResultData.fail(ResultData.REGISTER_FAIL, "手机号格式不正确");
        }

        if(!CheckInfoUtils.isEmail(sysUser.getEmail())){
            return ResultData.fail(ResultData.REGISTER_FAIL, "邮箱格式不正确");
        }

        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        // 手机号、邮箱、用户名判重
        if(sysUser.getMobile() != null){
            queryWrapper.eq("mobile", sysUser.getMobile());
            SysUser sysUser1 = sysUserDAO.selectOne(queryWrapper);
            if(sysUser1 != null){
                return ResultData.ok(ResultData.REGISTER_FAIL, "手机号已存在");
            }
            // 清空查询条件，便于后续判断
            queryWrapper.clear();
        }

        if(sysUser.getEmail() != null){
            queryWrapper.eq("email", sysUser.getEmail());
            SysUser sysUser1 = sysUserDAO.selectOne(queryWrapper);
            if(sysUser1 != null){
                return ResultData.ok(ResultData.REGISTER_FAIL, "邮箱已存在");
            }
            queryWrapper.clear();
        }

        if(sysUser.getUsername() != null){
            queryWrapper.eq("username", sysUser.getUsername());
            SysUser sysUser1 = sysUserDAO.selectOne(queryWrapper);
            if(sysUser1 != null){
                return ResultData.ok(ResultData.REGISTER_FAIL, "用户名已存在");
            }
        }

        return ResultData.ok(ResultData.VERIFY_SUCCESS, "用户信息验证通过");
    }

    /**
     * 使用事务管理@Transactional注解
     * 传播方式为REQUIRED（没有自己创建，有就用外部的）
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public Integer sysUserRegister(SysUser sysUser) {
        /*
            插入数据，由于手机号不能为空且唯一，所以可以作为查询条件查到该用户的主键值
                然后用于将user_id存放在用户-角色表中（客户端用户注册统一为普通用户）
         */
        int result = sysUserDAO.insert(sysUser);
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", sysUser.getMobile());
        SysUser sysUser1 = sysUserDAO.selectOne(queryWrapper);
        int result2 = sysUserRoleDAO.insert(new SysUserRole(null, sysUser1.getUserId(), 28L));
        return result2;
    }

    @Override
    public SysUser findUserByUserMobile(String mobile) {
        SysUser sysUser = sysUserDAO.selectOne(new QueryWrapper<SysUser>().eq("mobile", mobile));
        return sysUser;
    }

    /**
     * 用户使用手机验证码登录成功后逻辑
     * @param sysUser
     * @return
     */
    @Override
    public Authentication addUserInfoToUserDetails(SysUser sysUser) {

        List<SysRole> roles = sysRoleDAO.selectSysRolesByUsername(sysUser.getUsername());
        // 放入权限集合
        Collection<GrantedAuthority> authorities = new HashSet<>();
        for (SysRole role : roles) {
            authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + role.getRoleName()));
        }

        // 存入Spring Security中UserDetails的默认实现类User中，返回
        UserDetails userDetails = new org.springframework.security.core.userdetails.User(
                sysUser.getUsername(), "{noop}" + sysUser.getPassword(),
                true, true, true, true,
                authorities
        );

        Authentication authentication =new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);

        return authentication;
    }


}
